#pip install -i https://pypi.doubanio.com/simple paho-mqtt
from paho.mqtt import client as mqtt_client
print('load mqtt_client libs...')
import random
import time
import threading


class TMqttClient:
    def __init__(self):
        try:
            self.confgi={
                "host":"",
                "port":0,
                "uid":"",
                "pwd":""
            }
            self.events={
                "onConnect":None,  # ( status )=>{}
                "onDisconnect":None,  # (  )=>{}
                "onMessage":None,  # ( topic , payload , msg )=>{}
            }
            self.clientId = ""
            self.client = None
        except Exception as er :
            print(er)
    def open(self):
        try:
            def onconnect(client, userdata, flags, rc):
                try:
                    status = 1 if rc==0 else 0
                    if self.events["onconnect"]!=None:
                        self.events['onconnect'](status)
                    print('connect mqtt broker.rc='+ str(rc)+")")
                except Exception as onConnError:
                    print(onConnError)
            def ondisconnect(client, userdata, rc):
                try:
                    FIRST_RECONNECT_DELAY = 1
                    RECONNECT_RATE = 2
                    MAX_RECONNECT_COUNT = 12
                    MAX_RECONNECT_DELAY = 60
                    reconnect_count, reconnect_delay = 0, FIRST_RECONNECT_DELAY
                    while reconnect_count < MAX_RECONNECT_COUNT:
                        time.sleep(reconnect_delay)
                        try:
                            client.reconnect()
                            #logging.info("Reconnected successfully!")
                            return
                        except Exception as err:
                            print("%s. Reconnect failed. Retrying...", err)
                            #logging.error("%s. Reconnect failed. Retrying...", err)
                        reconnect_delay *= RECONNECT_RATE
                        reconnect_delay = min(reconnect_delay, MAX_RECONNECT_DELAY)
                        reconnect_count += 1
                except Exception as onDisConnError:
                    print(onDisConnError)
            def onmessage(client, userdata, msg):
                try:
                    topic = msg.topic
                    payload = msg.payload.decode()
                    print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")
                    if ( self.events["onmessage"]!=None):
                        self.events['onmessage'](topic , payload , msg)
                except Exception as onMessage:
                    print(onMessage)
            clientId =  f'cid-{random.randint(0, 1000)}'
            client = mqtt_client.Client(clientId)
            client.on_connect= onconnect
            client.on_disconnect = ondisconnect
            client.on_message = onmessage
            client.username_pw_set(self.config['uid'], self.config['pwd'])
            client.connect(host=self.config['host'],port=self.config['port'], clean_start=True, keepalive=60)
            self.client = client
            self.clientId = clientId
            self.client.loop_forever()
        except Exception as er :
            print(er)

    def openAsync(self):
        try:
            th = threading.Thread(target= self.open, daemon=True)
            th.start()
        except Exception as eer:
            print(eer)
    def isOpenned(self):
        res = False
        try:
            if self.client!=None:
                res = self.client.is_connected()
        except Exception as eer:
            print(eer)
        return  res
